#include "StdAfx.h"

#if USE_CRYLOBBY_GAMESPY

#include "CryGameSpyLobby.h"
#include "CryGameSpyFriendsManagement.h"

#define MAX_FRIENDS_MANAGEMENT_TASK_TIME						(10000)
// Number params
#define FRIENDS_MANAGEMENT_PARAM_NUM_USERS					(0)
#define FRIENDS_MANAGEMENT_PARAM_MAX_USERS					(1)
#define FRIENDS_MANAGEMENT_PARAM_CURRENT_GPPROFILE	(2)
// Memory params
#define FRIENDS_MANAGEMENT_PARAM_INPUT_DATA					(0)
#define FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT			(1)
#define FRIENDS_MANAGEMENT_PARAM_USERS_RESULT				(1)
#define FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT			(1)

CCryGameSpyFriendsManagement::CCryGameSpyFriendsManagement(CCryLobby* pLobby, CCryLobbyService* pService)
: CCryFriendsManagement(pLobby, pService)
, m_pGPConnection(NULL)
, m_GPProfile(0)
{
	// Make the CCryFriendsManagement base pointers point to our data so we can use the common code in CCryFriendsManagement
	for (uint32 index = 0; index < MAX_FRIENDS_MANAGEMENT_TASKS; ++index)
	{
		CCryFriendsManagement::m_pTask[index] = &m_task[index];
	}
}

void CCryGameSpyFriendsManagement::Tick(CTimeValue tv)
{
	for (uint32 i = 0; i < MAX_FRIENDS_MANAGEMENT_TASKS; i++)
	{
		STask* pTask = &m_task[i];

		if (pTask->used && pTask->running)
		{
			if ((!pTask->m_taskStarted) && pTask->m_haveGPConnection)
			{
				pTask->m_taskStarted = true;
				pTask->m_timeStarted = g_time;

				switch (pTask->startedTask)
				{
				case eT_FriendsManagementSendFriendRequest:
					StartFriendsManagementSendFriendRequest(i);
					break;
				case eT_FriendsManagementAcceptFriendRequest:
					StartFriendsManagementAcceptFriendRequest(i);
					break;
				case eT_FriendsManagementRejectFriendRequest:
					StartFriendsManagementRejectFriendRequest(i);
					break;
				case eT_FriendsManagementRevokeFriendStatus:
					StartFriendsManagementRevokeFriendStatus(i);
					break;
				case eT_FriendsManagementIsUserFriend:
					StartFriendsManagementIsUserFriend(i);
					break;
				case eT_FriendsManagementFindUser:
					StartFriendsManagementFindUser(i);
					break;
				case eT_FriendsManagementBlockUser:
					StartFriendsManagementBlockUser(i);
					break;
				case eT_FriendsManagementUnblockUser:
					StartFriendsManagementUnblockUser(i);
					break;
				case eT_FriendsManagementIsUserBlocked:
					StartFriendsManagementIsUserBlocked(i);
					break;
				case eT_FriendsManagementAcceptInvite:
					StartFriendsManagementAcceptInvite(i);
					break;
				case eT_FriendsManagementGetStatus:
					StartFriendsManagementGetStatus(i);
					break;
				}
			}

			if (pTask->m_taskStarted)
			{
				switch (pTask->subTask)
				{
				case eT_FriendsManagementSendFriendRequest:
					TickFriendsManagementSendFriendRequest(i);
					break;
				case eT_FriendsManagementAcceptFriendRequest:
					TickFriendsManagementAcceptFriendRequest(i);
					break;
				case eT_FriendsManagementRejectFriendRequest:
					TickFriendsManagementRejectFriendRequest(i);
					break;
				case eT_FriendsManagementRevokeFriendStatus:
					TickFriendsManagementRevokeFriendStatus(i);
					break;
				case eT_FriendsManagementIsUserFriend:
					TickFriendsManagementIsUserFriend(i);
					break;
				case eT_FriendsManagementFindUser:
					TickFriendsManagementFindUser(i);
					break;
				case eT_FriendsManagementBlockUser:
					TickFriendsManagementBlockUser(i);
					break;
				case eT_FriendsManagementUnblockUser:
					TickFriendsManagementUnblockUser(i);
					break;
				case eT_FriendsManagementIsUserBlocked:
					TickFriendsManagementIsUserBlocked(i);
					break;
				case eT_FriendsManagementAcceptInvite:
					TickFriendsManagementAcceptInvite(i);
					break;
				case eT_FriendsManagementGetStatus:
					TickFriendsManagementGetStatus(i);
					break;
				}
			}
		}
	}
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementSendFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementSendFriendRequest, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementSendFriendRequest(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementAcceptFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementAcceptFriendRequest, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementAcceptFriendRequest(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementRejectFriendRequest(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementRejectFriendRequest, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementRejectFriendRequest(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementRevokeFriendStatus(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementRevokeFriendStatus, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementRevokeFriendStatus(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementIsUserFriend(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementInfoCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementIsUserFriend, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementIsUserFriend(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementFindUser(uint32 user, SFriendManagementSearchInfo* pUserName, uint32 maxResults, CryLobbyTaskID* pTaskID, CryFriendsManagementSearchCallback pCb, void* pCbArg)
{
	LOBBY_AUTO_LOCK;

	ECryLobbyError error = eCLE_Success;
	CryFriendsTaskID fTaskID;

	error = StartTask(eT_FriendsManagementFindUser, false, user, &fTaskID, pTaskID, CrySessionInvalidHandle, pCb, pCbArg);
	if (error == eCLE_Success)
	{
		STask* pTask = &m_task[fTaskID];
		pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_MAX_USERS] = maxResults;
		error = CreateTaskParamMem(fTaskID, FRIENDS_MANAGEMENT_PARAM_INPUT_DATA, NULL, sizeof(SFriendManagementSearchInfo));

		if ((error == eCLE_Success) && (pUserName->name[0] != 0))
		{
			SFriendManagementSearchInfo* pName = (SFriendManagementSearchInfo*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
			strncpy(pName->name, pUserName->name, CRYLOBBY_USER_NAME_LENGTH - 1);
			pName->name[CRYLOBBY_USER_NAME_LENGTH - 1] = 0;

			FROM_GAME_TO_LOBBY(&CCryGameSpyFriendsManagement::StartTaskRunning, this, fTaskID);
		}
		else
		{
			FreeTask(fTaskID);
		}
	}

	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementFindUser(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementBlockUser(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementBlockUser, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementBlockUser(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementUnblockUser(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementUnblockUser, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementUnblockUser(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementIsUserBlocked(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementInfoCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementIsUserBlocked, user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementIsUserBlocked(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementAcceptInvite(uint32 user, CryUserID* pUserID, CryLobbyTaskID* pTaskID, CryFriendsManagementCallback pCb, void* pCbArg)
{
	ECryLobbyError error = InitialiseTask(eT_FriendsManagementAcceptInvite, user, pUserID, 1, pTaskID, pCb, pCbArg);
	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementAcceptInvite(), result %d", error);
	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementGetName(uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementSearchCallback pCb, void* pCbArg)
{
	CCryGameSpyFriends* pFriends = (CCryGameSpyFriends*)m_pLobby->GetFriends();
	return pFriends->FriendsGetNamesList(user, pUserIDs, numUserIDs, pTaskID, pCb, pCbArg);
}

void CCryGameSpyFriendsManagement::OnGameSpyObjectAvailable(EGameSpyObjectBit object)
{
	if (object & eGSOB_GPConnection)
	{
		for (uint32 index = 0; index < MAX_FRIENDS_MANAGEMENT_TASKS; ++index)
		{
			STask* pTask = &m_task[index];

			if (pTask->used)
			{
				pTask->m_haveGPConnection = true;
			}
		}
	}
}

void CCryGameSpyFriendsManagement::OnGameSpyObjectUnavailable(EGameSpyObjectBit object)
{
	if (object & eGSOB_GPConnection)
	{
		for (uint32 index = 0; index < MAX_FRIENDS_MANAGEMENT_TASKS; ++index)
		{
			STask* pTask = &m_task[index];

			if (pTask->used)
			{
				pTask->m_haveGPConnection = false;

				switch (pTask->startedTask)
				{
				case eT_FriendsManagementSendFriendRequest:
				case eT_FriendsManagementAcceptFriendRequest:
				case eT_FriendsManagementRejectFriendRequest:
				case eT_FriendsManagementRevokeFriendStatus:
				case eT_FriendsManagementIsUserFriend:
				case eT_FriendsManagementFindUser:
				case eT_FriendsManagementBlockUser:
				case eT_FriendsManagementUnblockUser:
				case eT_FriendsManagementIsUserBlocked:
				case eT_FriendsManagementAcceptInvite:
					if (pTask->m_taskStarted)
					{
						UpdateTaskError(index, eCLE_UserNotSignedIn);
					}
					break;
				default:
					NetLogAlways( "[GameSpy] Task type %d not handled by CCryGameSpyFriendsManagement::OnGameSpyObjectUnavailable", pTask->startedTask );
					break;
				}
			}
		}
	}
}

void CCryGameSpyFriendsManagement::OnGameSpyObjectCantMakeAvailable(EGameSpyObjectBit object)
{
	if (object & eGSOB_GPConnection)
	{
		for (uint32 index = 0; index < MAX_FRIENDS_MANAGEMENT_TASKS; ++index)
		{
			STask* pTask = &m_task[index];

			if (pTask->used)
			{
				switch (pTask->startedTask)
				{
				case eT_FriendsManagementSendFriendRequest:
				case eT_FriendsManagementAcceptFriendRequest:
				case eT_FriendsManagementRejectFriendRequest:
				case eT_FriendsManagementRevokeFriendStatus:
				case eT_FriendsManagementIsUserFriend:
				case eT_FriendsManagementFindUser:
				case eT_FriendsManagementBlockUser:
				case eT_FriendsManagementUnblockUser:
				case eT_FriendsManagementIsUserBlocked:
				case eT_FriendsManagementAcceptInvite:
					UpdateTaskError(index, eCLE_UserNotSignedIn);
					break;
				default:
					NetLogAlways( "[GameSpy] Task type %d not handled by CCryGameSpyFriendsManagement::OnGameSpyObjectCantMakeAvailable", pTask->startedTask );
					break;
				}
			}
		}
	}
}

void CCryGameSpyFriendsManagement::LateInitialise(GPConnection* pGPConnection, GPProfile gpProfile, _smart_ptr<CCryGameSpyFriends> pFriends)
{
	m_pGPConnection = pGPConnection;
	m_GPProfile = gpProfile;
	m_pFriends = pFriends;
}

ECryLobbyError CCryGameSpyFriendsManagement::InitialiseTask(ETask taskType, uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, void* pCb, void* pCbArg)
{
	LOBBY_AUTO_LOCK;

	ECryLobbyError error = eCLE_Success;
	CryFriendsTaskID fTaskID;

	error = StartTask(taskType, false, user, &fTaskID, pTaskID, CrySessionInvalidHandle, pCb, pCbArg);
	if (error == eCLE_Success)
	{
		STask* pTask = &m_task[fTaskID];
		pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] = numUserIDs;

		if (numUserIDs > 0)
		{
			error = CreateTaskParamMem(fTaskID, FRIENDS_MANAGEMENT_PARAM_INPUT_DATA, NULL, numUserIDs*sizeof(GPProfile));

			if (error == eCLE_Success)
			{
				GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);

				for (uint32 index = 0; index < numUserIDs; index++)
				{
					if (pUserIDs[index].IsValid())
					{
						pGPProfiles[index] = ((const SCryGameSpyUserID*)pUserIDs[index].get())->m_profileID;
					}
					else
					{
						error = eCLE_InvalidUser;
						break;
					}
				}
			}
		}

		if (error == eCLE_Success)
		{
			FROM_GAME_TO_LOBBY(&CCryGameSpyFriendsManagement::StartTaskRunning, this, fTaskID);
		}
		else
		{
			FreeTask(fTaskID);
		}
	}

	return error;
}

ECryLobbyError CCryGameSpyFriendsManagement::StartTask(ETask etask, bool startRunning, uint32 user, CryFriendsManagementTaskID* pFTaskID, CryLobbyTaskID* pLTaskID, CrySessionHandle h, void* pCb, void* pCbArg)
{
	CryFriendsManagementTaskID tmpFTaskID;
	CryFriendsManagementTaskID* pUseFTaskID = pFTaskID ? pFTaskID : &tmpFTaskID;
	ECryLobbyError error = CCryFriendsManagement::StartTask(etask, startRunning, pUseFTaskID, pLTaskID, h, pCb, pCbArg);

	if (error == eCLE_Success)
	{
		STask* pTask = &m_task[*pUseFTaskID];

		if ( static_cast< CCryGameSpyLobbyService* >( m_pService )->GetAvailableGameSpyObjects() & eGSOB_GPConnection )
		{
			pTask->m_haveGPConnection = true;
		}

		pTask->m_taskStarted = false;		// Used to hold the task until the various external gamespy services are ready (for tasks that require this)
	}

	return error;
}

void CCryGameSpyFriendsManagement::StartTaskRunning(CryFriendsManagementTaskID fTaskID)
{
	LOBBY_AUTO_LOCK;

	STask* pTask = &m_task[fTaskID];

	if (pTask->used)
	{
		pTask->running = true;

		switch (pTask->startedTask)
		{
		case eT_FriendsManagementSendFriendRequest: // intentional fall-through
		case eT_FriendsManagementAcceptFriendRequest:
		case eT_FriendsManagementRejectFriendRequest:
		case eT_FriendsManagementRevokeFriendStatus:
		case eT_FriendsManagementIsUserFriend:
		case eT_FriendsManagementFindUser:
		case eT_FriendsManagementBlockUser:
		case eT_FriendsManagementUnblockUser:
		case eT_FriendsManagementIsUserBlocked:
		case eT_FriendsManagementAcceptInvite:
			GetService()->SetNeedGPConnection(true);
			break;
		}
	}
}

void CCryGameSpyFriendsManagement::EndTask(CryFriendsManagementTaskID fTaskID)
{
	LOBBY_AUTO_LOCK;

	STask* pTask = &m_task[fTaskID];

	if (pTask->used)
	{
		if (pTask->pCb)
		{
			switch (pTask->startedTask)
			{
			case eT_FriendsManagementSendFriendRequest:
			case eT_FriendsManagementAcceptFriendRequest:	// intentional fall-through
			case eT_FriendsManagementRejectFriendRequest:	// intentional fall-through
			case eT_FriendsManagementRevokeFriendStatus:	// intentional fall-through
			case eT_FriendsManagementBlockUser:						// intentional fall-through
			case eT_FriendsManagementUnblockUser:					// intentional fall-through
			case eT_FriendsManagementAcceptInvite:				// intentional fall-through
				((CryFriendsManagementCallback)pTask->pCb)(pTask->lTaskID, pTask->error, pTask->pCbArg);
				break;

			case eT_FriendsManagementIsUserFriend:
				EndFriendsManagementIsUserFriend(fTaskID);
				break;

			case eT_FriendsManagementFindUser:
				EndFriendsManagementFindUser(fTaskID);
				break;

			case eT_FriendsManagementIsUserBlocked:
				EndFriendsManagementIsUserBlocked(fTaskID);
				break;

			case eT_FriendsManagementGetStatus:
				EndFriendsManagementGetStatus(fTaskID);
				break;
			}
		}

		if (pTask->error != eCLE_Success)
		{
			NetLog("[Lobby] CCryGameSpyFriendsManagement::EndTask() %d (%d) Result %d", pTask->startedTask, pTask->subTask, pTask->error);
		}

		FreeTask(fTaskID);
	}
}

void CCryGameSpyFriendsManagement::StopTaskRunning(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];

	if (pTask->used)
	{
		pTask->running = false;

		TO_GAME_FROM_LOBBY(&CCryGameSpyFriendsManagement::EndTask, this, fTaskID);
	}
}

void CCryGameSpyFriendsManagement::StartFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{		
		UpdateTaskError( fTaskID, static_cast< CCryGameSpyFriends* >( m_pLobby->GetFriends() )->FriendsSendFriendRequest( pGPProfiles[index], "Crysis2 in-game friends request" ) );
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementSendFriendRequest() sent friend request to profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementSendFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{
		UpdateTaskError( fTaskID, static_cast< CCryGameSpyFriends* >( m_pLobby->GetFriends() )->FriendsAcceptFriendRequest( pGPProfiles[index] ) );
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementAcceptFriendRequest() accepted friend request from profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementAcceptFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{
		UpdateTaskError( fTaskID, static_cast< CCryGameSpyFriends* >( m_pLobby->GetFriends() )->FriendsDenyFriendRequest( pGPProfiles[index] ) );
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementRejectFriendRequest() rejected friend request from profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementRejectFriendRequest(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{
		UpdateTaskError( fTaskID, static_cast< CCryGameSpyFriends* >( m_pLobby->GetFriends() )->FriendsRevokeFriendStatus( pGPProfiles[index] ) );
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementRevokeFriendStatus() revoked friend status with profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementRevokeFriendStatus(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];
	ECryLobbyError error = CreateTaskParamMem(fTaskID, FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT, NULL, numUserIDs*sizeof(bool));

	if (error == eCLE_Success)
	{
		bool* pResult = (bool*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT]);
		for (uint32 index = 0; index < numUserIDs; ++index)
		{
			if (gpIsBuddy(m_pGPConnection, pGPProfiles[index]) == gsi_true)
			{
				pResult[index] = true;
				NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementIsUserFriend() profile 0x%08x is a friend", pGPProfiles[index]);
			}
			else
			{
				pResult[index] = false;
				NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementIsUserFriend() profile 0x%08x is NOT a friend", pGPProfiles[index]);
			}
		}
	}
	else
	{
		UpdateTaskError(fTaskID, error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementIsUserFriend(CryFriendsManagementTaskID fTaskID)
{
	EndFriendsManagementTaskWithInfo(fTaskID);
}

void CCryGameSpyFriendsManagement::StartFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	SFriendManagementSearchInfo* pName = (SFriendManagementSearchInfo*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);

	SConfigurationParams neededInfo[1] = { CLCC_GAMESPY_NAMESPACEID, {NULL} };
	m_pLobby->GetConfigurationInformation(neededInfo, 1);
	int namespaceID[1] = { neededInfo[0].m_32 };

	pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_CURRENT_GPPROFILE] = m_GPProfile;
	UpdateTaskError(fTaskID, CCryGameSpyLobbyService::GetErrorFromGameSpy(gpProfileSearchUniquenick(m_pGPConnection, pName->name, namespaceID, 1, GP_NON_BLOCKING, FindUserCallback, this), m_pGPConnection));

	if (pTask->error != eCLE_Success)
	{
		StopTaskRunning(fTaskID);
	}
}

void CCryGameSpyFriendsManagement::TickFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];

	uint64 timeTaken = (g_time - pTask->m_timeStarted).GetMilliSecondsAsInt64();

	if ((pTask->used) && (timeTaken > MAX_FRIENDS_MANAGEMENT_TASK_TIME))
	{
		StopTaskRunning(fTaskID);
	}
}

void CCryGameSpyFriendsManagement::EndFriendsManagementFindUser(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	SFriendInfo* pInfo = (SFriendInfo*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_USERS_RESULT]);
	uint32 numResults = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	if (pTask->error == eCLE_Success)
	{
		((CryFriendsManagementSearchCallback)pTask->pCb)(pTask->lTaskID, pTask->error, pInfo, numResults, pTask->pCbArg);
	}
	else
	{
		((CryFriendsManagementSearchCallback)pTask->pCb)(pTask->lTaskID, pTask->error, NULL, 0, pTask->pCbArg);
	}
}

void CCryGameSpyFriendsManagement::StartFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{
		UpdateTaskError(fTaskID, CCryGameSpyLobbyService::GetErrorFromGameSpy(gpAddToBlockedList(m_pGPConnection, pGPProfiles[index]), m_pGPConnection));
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementBlockUser() blocked profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementBlockUser(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	for (uint32 index = 0; index < numUserIDs; ++index)
	{
		UpdateTaskError(fTaskID, CCryGameSpyLobbyService::GetErrorFromGameSpy(gpRemoveFromBlockedList(m_pGPConnection, pGPProfiles[index]), m_pGPConnection));
		NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementUnblockUser() unblocked profile 0x%08x, result %d", pGPProfiles[index], pTask->error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementUnblockUser(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::StartFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];
	ECryLobbyError error = CreateTaskParamMem(fTaskID, FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT, NULL, numUserIDs*sizeof(bool));

	if (error == eCLE_Success)
	{
		bool* pResult = (bool*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT]);
		for (uint32 index = 0; index < numUserIDs; ++index)
		{
			if (gpIsBlocked(m_pGPConnection, pGPProfiles[index]) == gsi_true)
			{
				pResult[index] = true;
				NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementIsUserBlocked() profile 0x%08x is blocked", pGPProfiles[index]);
			}
			else
			{
				pResult[index] = false;
				NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementIsUserBlocked() profile 0x%08x is NOT blocked", pGPProfiles[index]);
			}
		}
	}
	else
	{
		UpdateTaskError(fTaskID, error);
	}

	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementIsUserBlocked(CryFriendsManagementTaskID fTaskID)
{
	EndFriendsManagementTaskWithInfo(fTaskID);
}

void CCryGameSpyFriendsManagement::StartFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfile = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);

	SCryGameSpySessionID* pSessionID = new SCryGameSpySessionID;
	pSessionID->m_sid = m_pFriends->GetInviteSessionID(m_pGPConnection, *pGPProfile);
	memset(&pSessionID->m_addr, 0, sizeof(SCryGameSpyRemoteConnectionID));
	pSessionID->m_addr.m_state = eGSNT_NotStarted;
	pSessionID->m_addr.m_cookie = *pGPProfile ^ m_GPProfile;
	
	// TODO: need to create an invite accepted confirmation message which contains uniquely identifiable details (e.g. sid?)
	gpSendBuddyMessage(m_pGPConnection, *pGPProfile, "accepted");

	CCryGameSpyLobbyService* pGameSpyLobbyService = static_cast<CCryGameSpyLobbyService*>(m_pLobby->GetLobbyService(eCLS_Online));
	TO_GAME_FROM_LOBBY(&CCryGameSpyLobbyService::InviteAccepted, pGameSpyLobbyService, (uint32)0, CrySessionID(pSessionID));

	NetLog("[Lobby] CCryGameSpyFriendsManagement::StartFriendsManagementAcceptInvite() : invite to profile 0x%08x accepted");
	StopTaskRunning(fTaskID);
}

void CCryGameSpyFriendsManagement::TickFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

void CCryGameSpyFriendsManagement::EndFriendsManagementAcceptInvite(CryFriendsManagementTaskID fTaskID)
{
	// Nothing to do
}

CryFriendsManagementTaskID CCryGameSpyFriendsManagement::GetTaskID(GPConnection* pGPConnection, GPProfile gpProfile)
{
	STask* pTask = NULL;
	CryFriendsManagementTaskID fTaskID = 0;
	for (fTaskID = 0; fTaskID < MAX_FRIENDS_MANAGEMENT_TASKS; ++fTaskID)
	{
		pTask = &m_task[fTaskID];

		if ((m_pGPConnection == pGPConnection) && (pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_CURRENT_GPPROFILE] == gpProfile))
		{
			break;
		}
	}

	return (fTaskID < MAX_FRIENDS_MANAGEMENT_TASKS) ? fTaskID : CryFriendsManagementInvalidTaskID;
}

void CCryGameSpyFriendsManagement::EndFriendsManagementTaskWithInfo(CryFriendsManagementTaskID fTaskID)
{
	STask* pTask = &m_task[fTaskID];
	GPProfile* pGPProfiles = (GPProfile*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_INPUT_DATA]);
	bool* pResult = (bool*)m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_BOOLEAN_RESULT]);
	uint32 numUserIDs = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];

	SFriendManagementInfo* pInfo = new SFriendManagementInfo[numUserIDs];

	if (pInfo != NULL)
	{
		for (uint32 index = 0; (index < numUserIDs) && (pTask->error == eCLE_Success); ++index)
		{
			pInfo->userID = new SCryGameSpyUserID(pGPProfiles[index]);
			pInfo->result = pResult[index];

			if (pInfo->userID == NULL)
			{
				pTask->error = eCLE_OutOfMemory;
			}
		}
	}
	else
	{
		pTask->error = eCLE_OutOfMemory;
	}

	if (pTask->error == eCLE_Success)
	{
		((CryFriendsManagementInfoCallback)pTask->pCb)(pTask->lTaskID, pTask->error, pInfo, numUserIDs, pTask->pCbArg);
	}
	else
	{
		((CryFriendsManagementInfoCallback)pTask->pCb)(pTask->lTaskID, pTask->error, NULL, 0, pTask->pCbArg);
	}
}

void CCryGameSpyFriendsManagement::FindUserCallback(GPConnection* pGPConnection, void* pArg, void* pParam)
{
	CCryGameSpyFriendsManagement* _this = static_cast<CCryGameSpyFriendsManagement*>(pParam);
	if (pGPConnection == _this->m_pGPConnection)
	{
		GPProfileSearchResponseArg* pProfileSearchResponseArg = static_cast<GPProfileSearchResponseArg*>(pArg);
		CryFriendsManagementTaskID fTaskID = _this->GetTaskID(pGPConnection, _this->m_GPProfile);

		if (fTaskID != CryFriendsManagementInvalidTaskID)
		{
			STask* pTask = &_this->m_task[fTaskID];

			if ((pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] + pProfileSearchResponseArg->numMatches) > pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_MAX_USERS])
			{
				_this->UpdateTaskError(fTaskID, eCLE_OutOfUserData);
				_this->StopTaskRunning(fTaskID);

				NetLog("[Lobby] CCryGameSpyFriendsManagement::FindUserCallback() found too many matches (max requested %d, found %d)", pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] + pProfileSearchResponseArg->numMatches, pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_MAX_USERS]);
				return;
			}

			SFriendInfo* pInfo = (SFriendInfo*)_this->m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_USERS_RESULT]);

			if (pInfo != NULL)
			{
				// We've already got some data so amalgamate the new data with this
				uint32 newNumUsers = pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] + pProfileSearchResponseArg->numMatches;
				TMemHdl newHandle = _this->m_pLobby->MemAlloc(newNumUsers * sizeof(SFriendInfo));
				SFriendInfo* pNewInfo = static_cast<SFriendInfo*>(_this->m_pLobby->MemGetPtr(newHandle));
				memset(pNewInfo, 0, newNumUsers * sizeof(SFriendInfo));

				if (pNewInfo)
				{
					uint32 index = 0;
					for (; index < pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS]; ++index)
					{
						pNewInfo[index] = pInfo[index];
					}

					for (; index < newNumUsers; ++index)
					{
						uint32 callbackDataIndex = index - pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS];
						pNewInfo[index].userID = new SCryGameSpyUserID(pProfileSearchResponseArg->matches[callbackDataIndex].profile);
						strncpy(pNewInfo[index].name, pProfileSearchResponseArg->matches[callbackDataIndex].uniquenick, CRYLOBBY_USER_NAME_LENGTH - 1);

						if (pNewInfo[index].userID == NULL)
						{
							_this->UpdateTaskError(fTaskID, eCLE_OutOfMemory);
							_this->StopTaskRunning(fTaskID);
							_this->m_pLobby->MemFree(newHandle);
							NetLog("[Lobby] CCryGameSpyFriendsManagement::FindUserCallback() ran out of memory");
							return;
						}
					}

					if (pTask->error == eCLE_Success)
					{
						_this->m_pLobby->MemFree(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_USERS_RESULT]);
						pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_USERS_RESULT] = newHandle;
						pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] = newNumUsers;
					}
				}
				else
				{
					_this->UpdateTaskError(fTaskID, eCLE_OutOfMemory);
					_this->StopTaskRunning(fTaskID);
					NetLog("[Lobby] CCryGameSpyFriendsManagement::FindUserCallback() ran out of memory");
					return;
				}
			}
			else
			{
				_this->UpdateTaskError(fTaskID, _this->CreateTaskParamMem(fTaskID, FRIENDS_MANAGEMENT_PARAM_USERS_RESULT, NULL, pProfileSearchResponseArg->numMatches * sizeof(SFriendInfo)));

				if (pTask->error == eCLE_Success)
				{
					pInfo = (SFriendInfo*)_this->m_pLobby->MemGetPtr(pTask->paramsMem[FRIENDS_MANAGEMENT_PARAM_USERS_RESULT]);
					memset(pInfo, 0, pProfileSearchResponseArg->numMatches * sizeof(SFriendInfo));

					for (uint32 index = 0; index < pProfileSearchResponseArg->numMatches; ++index)
					{
						pInfo[index].userID = new SCryGameSpyUserID(pProfileSearchResponseArg->matches[index].profile);
						memset(pInfo[index].name, 0, CRYLOBBY_USER_NAME_LENGTH);
						strncpy(pInfo[index].name, pProfileSearchResponseArg->matches[index].uniquenick, CRYLOBBY_USER_NAME_LENGTH - 1);

						if (pInfo[index].userID == NULL)
						{
							_this->UpdateTaskError(fTaskID, eCLE_OutOfMemory);
							_this->StopTaskRunning(fTaskID);
							NetLog("[Lobby] CCryGameSpyFriendsManagement::FindUserCallback() ran out of memory");
							return;
						}
					}

					pTask->paramsNum[FRIENDS_MANAGEMENT_PARAM_NUM_USERS] = pProfileSearchResponseArg->numMatches;
				}
			}
		}
	}
}

ECryLobbyError CCryGameSpyFriendsManagement::FriendsManagementGetStatus( uint32 user, CryUserID* pUserIDs, uint32 numUserIDs, CryLobbyTaskID* pTaskID, CryFriendsManagementStatusCallback pCb, void* pCbArg )
{
	LOBBY_AUTO_LOCK;

	ECryLobbyError		error = eCLE_Success;
	CryFriendsTaskID	fTaskID;

	error = StartTask( eT_FriendsManagementGetStatus, false, user, &fTaskID, pTaskID, CrySessionInvalidHandle, pCb, pCbArg );

	if ( error == eCLE_Success )
	{
		STask*						pTask = &m_task[ fTaskID ];

		pTask->paramsNum[ FRIENDS_MANAGEMENT_PARAM_NUM_USERS ] = numUserIDs;

		if ( numUserIDs > 0 )
		{
			error = CreateTaskParamMem( fTaskID, FRIENDS_MANAGEMENT_PARAM_INPUT_DATA, NULL, numUserIDs * sizeof ( GPProfile ) );

			if ( error == eCLE_Success )
			{
				GPProfile*				pGPProfiles = ( GPProfile* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_INPUT_DATA ] );

				for ( uint32 index = 0; index < numUserIDs; ++index )
				{
					if ( pUserIDs[ index ].IsValid() )
					{
						pGPProfiles[ index ] = ( ( const SCryGameSpyUserID* )pUserIDs[ index ].get() )->m_profileID;
					}
					else
					{
						error = eCLE_InvalidUser;
						break;
					}
				}

				if ( error == eCLE_Success )
				{
					error = CreateTaskParamMem( fTaskID, FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT, NULL, numUserIDs * sizeof ( SFriendStatusInfo ) );

					if ( error == eCLE_Success )
					{
						SFriendStatusInfo*	pStatusInfo = ( SFriendStatusInfo* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT ] );

						for ( uint32 i = 0; i < numUserIDs; ++i )
						{
							new ( &pStatusInfo[ i ] ) SFriendStatusInfo();
						}
					}
				}				
			}
		}
		else
		{
			error = eCLE_InvalidRequest;
		}

		if ( error == eCLE_Success )
		{
			pTask->paramsNum[ FRIENDS_MANAGEMENT_PARAM_CURRENT_GPPROFILE ] = 0;
			FROM_GAME_TO_LOBBY( &CCryGameSpyFriendsManagement::StartTaskRunning, this, fTaskID );
		}
		else
		{
			FreeTask( fTaskID );
		}
	}

	NetLog("[Lobby] CCryGameSpyFriendsManagement::FriendsManagementGetStatus(), result %d", error);
	return error;
}

void CCryGameSpyFriendsManagement::StartFriendsManagementGetStatus( CryFriendsManagementTaskID fTaskID )
{
	ECryLobbyError			error;
	STask*							pTask = &m_task[ fTaskID ];
	GPProfile*					pGPProfiles = ( GPProfile* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_INPUT_DATA ] );
	SFriendStatusInfo*	pStatusInfo = ( SFriendStatusInfo* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT ] );

	for ( uint32 i = 0; ( i < pTask->paramsNum[ FRIENDS_MANAGEMENT_PARAM_NUM_USERS ] ) && ( pTask->error == eCLE_Success ); ++i )
	{
		error = m_pFriends->GetFriendStatus( pGPProfiles[ i ], &pStatusInfo[ i ] );

		if ( error != eCLE_Success )
		{
			UpdateTaskError( fTaskID, error );
		}
	}

	StopTaskRunning( fTaskID );
}

void CCryGameSpyFriendsManagement::TickFriendsManagementGetStatus( CryFriendsManagementTaskID fTaskID )
{
	// Nothing to do.
}

void CCryGameSpyFriendsManagement::EndFriendsManagementGetStatus( CryFriendsManagementTaskID fTaskID )
{
	STask*							pTask = &m_task[ fTaskID ];
	SFriendStatusInfo*	pStatusInfo = ( SFriendStatusInfo* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT ] );

	( ( CryFriendsManagementStatusCallback )pTask->pCb )( pTask->lTaskID, pTask->error, pStatusInfo, pTask->paramsNum[ FRIENDS_MANAGEMENT_PARAM_NUM_USERS ], pTask->pCbArg );
}

void CCryGameSpyFriendsManagement::FreeTask( CryFriendsManagementTaskID fTaskID )
{
	STask*							pTask = &m_task[ fTaskID ];

	switch ( pTask->startedTask )
	{
	case eT_FriendsManagementGetStatus:

		if ( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT ] != TMemInvalidHdl )
		{
			SFriendStatusInfo*	pStatusInfo = ( SFriendStatusInfo* )m_pLobby->MemGetPtr( pTask->paramsMem[ FRIENDS_MANAGEMENT_PARAM_STATUS_RESULT ] );

			for ( uint32 i = 0; i < pTask->paramsNum[ FRIENDS_MANAGEMENT_PARAM_NUM_USERS ]; ++i )
			{
				pStatusInfo[ i ].~SFriendStatusInfo();
			}
		}
		break;
	}

	CCryFriendsManagement::FreeTask( fTaskID );
}

#endif // USE_CRYLOBBY_GAMESPY
